/**************************************************************************
 * MODULE NAME:    l2_types.h
 * PROJECT CODE:
 * DESCRIPTION:    L2CAP Types
 * AUTHOR:         Gary Fleming
 * DATE:           02-08-1999
 *
 * SOURCE CONTROL: $Id: l2_types.h,v 1.3 2008/12/16 11:15:07 jianguo Exp $
 *
 * LICENSE:
 *     This source code is copyright (c) 2000 RDA Microelectronics, Ltd.
 *     All rights reserved.
 *
 **************************************************************************/

#ifndef __RDA_L2CAP_TYPES
#define __RDA_L2CAP_TYPES

#include "host_config.h"


#include "host_buf.h"
#include "l2cap_primitives.h"
#include "bd_addr_list.h"


/****************************************
 * Main States of the L2CAP State Machine
 *****************************************/

typedef enum {
    RDABT_L2_CLOSED,
    RDABT_L2_OPEN,
    RDABT_L2_CONFIG,
    RDABT_L2_SUSPENDED_TX,
    RDABT_L2_W4_LP_CONNECT_CFM,
    RDABT_L2_W4_L2CA_CONNECT_RSP,
    RDABT_L2_W4_L2CAP_CONNECT_RSP,
    RDABT_L2_W4_L2CA_DISCON_RSP,
    RDABT_L2_W4_L2CAP_DISCON_RSP
    } rdabt_t_l2_channel_states;


/****************************************
 * Config States of the L2CAP State Machine
 *****************************************/

typedef enum {
    RDABT_L2_CONFIG_START,
    RDABT_L2_REQUEST_RECEIVED,
    RDABT_L2_REQUEST_SENT,
    RDABT_L2_CONFIG_END
    } rdabt_t_l2_config_states;

#define RDA_IFRAME_MAX_TXWINDOW		63

#define RDA_I_FRAME		0
#define RDA_S_FRAME	1

/* transmission mode of specific l2cap channel */ 
enum
{
 	RDA_L2_BASIC_MODE = 0,
 	RDA_L2_RETRANS_MODE,
 	RDA_L2_FLOW_MODE,
 	RDA_L2_ENHANCED_MODE,
 	RDA_L2_STREAMING_MODE
};

//SAR flag definitions in I-Frames
enum
{
	RDA_L2_SAR_NULL = 0,
	RDA_L2_SAR_START,
	RDA_L2_SAR_END,
	RDA_L2_SAR_CONTINUE
};

typedef struct IFrame
{
	unsigned char TxSeq;
	unsigned char SAR;
	unsigned char TxCount;		/* send counter, */ 
	unsigned char *pBuf;			/* contain sdu, fcs, information payload filed*/
	unsigned int 	length;			/* buffer size of pBuf  */	
}IFrame_t;



/* Quality of service definitions */

typedef struct L2_ChannelFlowSpec {
	u_int8 flags;
	u_int8 serviceType;
	u_int32 tokenRate;
	u_int32 bucketSize;
	u_int32 peakBandwidth;
	u_int32 latency;
	u_int32 delayVariation;
} t_L2_ChannelFlowSpec ;


/* extended flow specification */
typedef struct tagExtendedFlowSpec
{
	u_int8 	identifier;
	u_int8 	serviceType;
	u_int16 	maxSDUsize;
	u_int32 	interArrivalTime;
	u_int32 	accessLatency;
	u_int32 	flushTimeout;	
}t_l2_ExtendedFlowSpec;


/***************************************************
 *  Structure describing an L2CAP channel
 ***************************************************/

typedef struct 
{
	t_L2_ChannelFlowSpec*    inQOS;
    t_L2_ChannelFlowSpec*   outQOS;
    u_int8        module_id;
    u_int16      flags;			/* Currently not used in the Bluetooth Ver 1.1 specification	*/
    u_int16      local_cid;     /* Identifer for local end of Channel			*/
    u_int16      remote_cid;    /* Identifer for remote end of Channel			*/
    u_int16      psm;           /* Identifer for Protocol using channel			*/
    u_int16      handle;		/* Handle for the ACL link the channel is using */
    u_int16      inMTU;			/* The size of the max allowed incoming MTU		*/
    u_int16      outMTU;		/* The size of the max allowed outgoing MTU		*/
    u_int16      inFlush;		/* The required incoming flush timeout			*/
    u_int16      outFlush;		/* The required outgoing flush timeout			*/
    void*        p_pdu;         /* Pointer to the current PDU on the channel	*/
    u_int8     timer_handle;	/* The timer handle								*/
    u_int8     config_timer_handle; /* The config timer handle                 */
	t_pMutex chn_lock;
	u_int8		 timer_active;	/* Identifies RTX or ERTX timer is active or not */
								/* 0x00  NO_TIMER								*/
								/* 0x01	 RTX_TIMER								*/
								/* 0x02  ERTX_TIMER								*/

    u_int8       remote_transaction_identifier;
    u_int8       local_transaction_identifier;
	u_int8       type;			/* Type of the channel -- Connection Oriented / Connectionless	*/
    rdabt_t_l2_config_states config_req_path; /* Current State of the config request path for the channel	*/
    rdabt_t_l2_config_states config_rsp_path; /* Current State of the config response path for the channel*/
    rdabt_t_l2_channel_states state;    /* Current State of the Channel         */
	List     *bda_list;

#if L2CAP_RETRANS_SUPPORT
	u_int8  	mode;
	u_int8 	txWindowSize;
	u_int8 	maxTransmit;
	u_int16	retransTimeInterval;
	u_int16	moniterTimeInterval;
	t_pTimer hRetransTimer;
	t_pTimer hMoniterTimer;
	u_int16 	maxPDUSize;
	u_int8 	NextTxSeq;
	u_int8 	ExpectedAckSeq;	// mod 64
	u_int8 	ExpectedTxSeq;		
	u_int8 	BufferSeq;
	IFrame_t IFrameWindow[RDA_IFRAME_MAX_TXWINDOW];
	u_int8 	FirstNonAckPos;  // mod TxWindowSize
	u_int8 	BufUsed;
	u_int8 	DisableBit;
	u_int8 	FCSPresent;			/* zero not support, or else support fcs */
	//st_rdabt_host_buf_t * pSDU;	
#endif	
} rdabt_t_l2_channel;


/************************************************
 * Structure Define an underlying ACL link
 * already established by the Link Manager 
 ************************************************/

typedef struct st_t_l2_acl_link {
    t_bdaddr	bd_addr;	/* The Bluetooth device address of peer on the link		*/
	t_L2_ChannelFlowSpec*    flow;
    void (*ping_callback)(t_bdaddr, u_int16, u_int8*, u_int16 );
    void (*info_callback)(t_bdaddr, u_int16, u_int8* ,u_int16 );
    u_int8*		cur_pos;
	u_int8*		echo_data;  /* pointer to echo data which transfered on the link	*/
    rdabt_host_buf_t* cur_buf;
    u_int8    timer_handle; /* The timer handle								*/
    u_int16		handle;		/* The HCI connection handle used to identify the link	*/
	u_int16		echo_len;	/* The length of the echo data to be transfered on the link		*/
	u_int16		info_type;	/* The type of information to be requested/recieved on an L2CAP information req/res */
    u_int16		cur_len;
    u_int16		segment_cid;
    u_int16		pending_cid;
    u_int16		length;
	u_int8		timer_active;	/* Identifies if a timer is active or not		*/
    u_int8		op_pending;
    u_int8		identifier;
	u_int8      initiator;
	t_pMutex    acl_lock;
    u_int8      mtu_complete; /* used for error handling in L2CAP sar */

#if AMP_MANAGER_SUPPORT==1
	u_int16 		ampGatherInfo;		
#endif
} rdabt_t_l2_acl_link;

/*************************************************
 * Structure describing the information required
 * to construct an L2CAP PDU. 
 * The opcode is contained and a pointer to the 
 * L2CAP channel sending the PDU.
 *************************************************/

typedef struct 
{
	t_L2_ChannelFlowSpec* qos;		/* A Quality of service field */
	rdabt_t_l2_channel* p_channel;	/* A pointer to a channel     */
	u_int8* p_data;					/* A pointer to a data field  */
    u_int16 length;					/* Length of the PDU          */
    u_int16 result;
    u_int16 status;
    u_int16 src_cid;
    u_int16 dest_cid; 
    u_int16 reason;
    u_int16 psm;
    u_int16 info_type;
    u_int16 mtu;
    u_int16 flush;
    u_int16 flags;
    u_int16 config_continue; 
    u_int8  opcode;
    u_int8  identifier;
    u_int8  num_options;
	u_int8  offset;
	
#if L2CAP_RETRANS_SUPPORT 
	u_int8  	mode;
	u_int8 	txWindowSize;
	u_int8 	maxTransmit;
	u_int16	retransTimeOut;
	u_int16	moniterTimeOut;
	u_int16 	maxPDUSize;
	u_int32  	ExtendFeature;
#endif

#if AMP_MANAGER_SUPPORT==1
	u_int16 	fcs;
	u_int16 	exWindowSize;
	u_int8 	controlID;
	u_int16 	initiator_cid;
	u_int8 	dest_controlID;
	u_int8 	fixedChnInfo[8];
	t_l2_ExtendedFlowSpec 	exFlowSpec;
#endif
	
} rdabt_t_l2_pdu;

#if RDABT_L2CAP_AUTO_CONFIG==1
typedef struct L2_ConfigReqParams{
  u_int16 inMTUmin;
  u_int16 inMTUmax;
  u_int16 outMTUmin;
  u_int16 outMTUmax;
  u_int16 flushTO;
  u_int16 linkTO;
} t_L2_ConfigReqParams;
#endif



/* The arguments of control events delivered to the upper layer */

typedef struct st_t_L2_controlCallbackArgs {
	t_bdaddr BDAddress;
	u_int16 psm;
	u_int16 cid;
        u_int16 mtu; 
	u_int16 flushTimeout;
	u_int16 status;
	u_int16 result;
	u_int8 timerType;    /* Identifies RTX or ERTX timer					*/
    u_int8 identifier;
	t_L2_ChannelFlowSpec *flow;
    struct st_rdabt_host_buf_t* p_buf;
#if (RDABT_L2CAP_AUTO_CONFIG==1)
  u_int16 mtu_in; /* only used by AUTOCONFIG */
#endif
} t_L2_ControlCallbackArgs ;

/* A structure of callback functions used to deliver events to the higher layers */

struct l2cap_cbs {
	void (*connectionIndication)(u_int16 eventType, t_L2_ControlCallbackArgs *args);
	void (*configureIndication)(u_int8 eventType, t_L2_ControlCallbackArgs *args);
	void (*disconnectionIndication)(u_int16 eventType, t_L2_ControlCallbackArgs *args);
	void (*qosviolationIndication)(u_int8 eventType,t_L2_ControlCallbackArgs *args);
	void (*connectionConfirmation)(u_int8 eventType, t_L2_ControlCallbackArgs *args);
	void (*configureConfirmation)(u_int8 eventType, t_L2_ControlCallbackArgs *args);
	void (*disconnectionConfirmation)(u_int16 eventType, t_L2_ControlCallbackArgs *args);  /* Unused ?? */
	void (*bufferOverflow)(u_int8 eventType,t_L2_ControlCallbackArgs *args); 
	void (*flushOccurred)(u_int8 eventType, t_L2_ControlCallbackArgs *args);
	void (*timeoutIndication)(u_int8 eventType,t_L2_ControlCallbackArgs *args);
	void (*dataIndication)(u_int16 cid, rdabt_host_buf_t* p_buf);
/*#if (PRH_L2CAP_AUTO_CONFIG==1)*/
        void (*connectionConfiguredConfirmation)(u_int16 eventType,t_L2_ControlCallbackArgs *args);
/*#endif*/
      
};


typedef struct {
    u_int16  psm;
    void (*addMemberCfm)(u_int16 cid,  t_bdaddr BDAddress, u_int16 status);
} rdabt_t_cls_psm;

typedef u_int16 t_psm;

struct l2cap_psm 
{
//  struct l2cap_cbs psm_cbs;
  t_psm psm;
  u_int8 state;
};

#endif
